const CONF_CONTAINER = document.getElementById('config')
const MAIN_CONTAINER = document.getElementById('main')
function showConfigContainer() {
	CONF_CONTAINER.classList.remove('hidden')
	MAIN_CONTAINER.classList.add('hidden')
}
function showMainContainer() {
	CONF_CONTAINER.classList.add('hidden')
	MAIN_CONTAINER.classList.remove('hidden')
}
function clearElements() {
	MAIN_CONTAINER.innerHTML = ''
}
function addElement(element) {
	MAIN_CONTAINER.appendChild(element)
}
function createTextElement(text = '&nbsp;', className = '') {
	let textElement = document.createElement('div')
	textElement.style.display = 'flex'
	textElement.style.alignItems = 'center'

	textElement.innerHTML = text
	textElement.className = className

	return textElement
}
function addTextElement(text = '&nbsp;', className = '') {
	addElement(createTextElement(text, className))
}
function test(title, expected, output) {
	if (output === expected) {
		addTextElement(`${title}：${expected}`, 'green')
	} else {
		addTextElement(`${title}：${expected} （输出：${output}）`, 'red')
	}
}
function createHandElement(hand, playing = false, discarding = undefined, ended = false, hu = false) {
	let handElement = document.createElement('div')
	handElement.style.display = 'flex'
	handElement.style.alignItems = 'center'

	let titleElement = document.createElement('span')
	titleElement.innerHTML = '手牌&nbsp;'
	handElement.appendChild(titleElement)

	let tilesElement = document.createElement('div')
	tilesElement.className = 'mahjong tiles'
	if (hand.melds) {
		for (const meld of hand.melds) {
			let tiles = structuredClone(meld[3])
			if (meld[2]) {
				tiles.push(meld[2])
			}
			tiles.sort(compareTiles)

			for (let i = 0; i < tiles.length; ++i) {
				const tile = tiles[i]
				let tileElement = document.createElement('ruby')
				tileElement.innerHTML = (meld[0] === CHOICE_CONCEALED_KONG && (i === 0 || i === 3)) ? '0z' : getTileText(tile)
				tilesElement.appendChild(tileElement)
			}
			let spaceElement = document.createElement('div')
			spaceElement.innerHTML = '_'
			tilesElement.appendChild(spaceElement)
		}
	}
	if (hand.tiles) {
		let tiles = hand.tiles
		if (!(playing || ended || hu)) {
			tiles = tiles.map(_ => TILE_Z0)
		}
		for (const tile of tiles) {
			let tileElement = document.createElement('ruby')
			tileElement.innerHTML = getTileText(tile)
			if (discarding !== undefined) {
				// Add discard ui
				tileElement.classList.add('clickable')
				tileElement.addEventListener('click', () => discarding(tile))
			}
			tilesElement.appendChild(tileElement)
		}
	}
	handElement.appendChild(tilesElement)

	return handElement
}
function addHandElement(hand, playing, discarding = undefined, ended = false, hu = false) {
	addElement(createHandElement(hand, playing, discarding, ended, hu))
}
function createDiscardElement(discard, discardLast) {
	let discardElement = document.createElement('div')
	discardElement.style.display = 'flex'
	discardElement.style.alignItems = 'center'

	let titleElement = document.createElement('span')
	titleElement.innerHTML = '出牌&nbsp;'
	discardElement.appendChild(titleElement)

	let tilesElement = document.createElement('div')
	tilesElement.className = 'mahjong tiles'
	if (discard.length) {
		for (let i = 0; i < discard.length; ++i) {
			if (discardLast && discard.length > 1 && i === discard.length - 1) {
				let spaceElement = document.createElement('div')
				spaceElement.innerHTML = '_'
				tilesElement.appendChild(spaceElement)
			}
			const tile = discard[i]
			let tileElement = document.createElement('ruby')
			tileElement.innerHTML = getTileText(tile)
			tilesElement.appendChild(tileElement)
		}
	} else {
		// Add a blank tile to fix element height
		let blankElement = document.createElement('ruby')
		blankElement.innerHTML = '0z'
		tilesElement.appendChild(blankElement)
	}
	discardElement.appendChild(tilesElement)

	return discardElement
}
function addDiscardElement(discard, discardLast) {
	addElement(createDiscardElement(discard, discardLast))
}
function createChoicesElement(choices, choosing, ended, ending) {
	let choicesElement = document.createElement('div')
	choicesElement.style.display = 'flex'
	choicesElement.style.alignItems = 'center'

	if (choices.length && choosing) {
		for (const choice of choices) {
			let choiceElement = document.createElement('div')
			choiceElement.className = 'clickable button'
			choiceElement.innerHTML = TEXT_CHOICE[choice[0]]
			if (choice[3]) {
				let tilesElement = document.createElement('div')
				tilesElement.className = 'mahjong'
				tilesElement.style.display = 'inline-block'
				tilesElement.innerHTML = choice[3].map(getTileText).join('')
				choiceElement.appendChild(tilesElement)
			}
			choiceElement.addEventListener('click', () => choosing(choice))
			choicesElement.appendChild(choiceElement)
		}
	} else if (ended && ending) {
		let advanceElement = document.createElement('div')
		advanceElement.className = 'clickable button'
		advanceElement.innerHTML = '继续'
		advanceElement.addEventListener('click', ending)
		choicesElement.appendChild(advanceElement)
	} else {
		let blankElement = document.createElement('div')
		blankElement.className = 'button'
		blankElement.innerHTML = '&nbsp;'
		choicesElement.appendChild(blankElement)
	}

	return choicesElement
}
function addChoicesElement(choices, choosing, ended, ending) {
	addElement(createChoicesElement(choices, choosing, ended, ending))
}
function addPlayerElement(player, playing, choices, choosing, discarding = undefined, discardLast = false, ended, ending) {
	addHandElement(player.hand, playing, discarding, ended, player.hu)
	addDiscardElement(player.discard, discardLast)
	addChoicesElement(choices, choosing, ended, ending)
}
function addGameElement(game) {
	if (game.ended) {
		// Game has ended
		addTextElement('终局', 'title')
		addTextElement()
		let players = game.points.map((v, i) => ({ points: v, playerId: i }))
		players.sort((a, b) => b.points - a.points)

		for (let i = 0; i < playerCount; ++i) {
			const points = players[i].points
			let fi = 0
			while (players[fi].points !== points) {
				++fi
			}
			addTextElement(`${fi + 1}位：${PLAYER_NAMES[players[i].playerId]}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;得分：${points}点`, playing[players[i].playerId] ? 'bold title2' : 'title2')
		}

		addTextElement()

		let choicesElement = document.createElement('div')
		choicesElement.style.display = 'flex'
		choicesElement.style.alignItems = 'center'

		let restartElement = document.createElement('div')
		restartElement.className = 'clickable button'
		restartElement.innerHTML = '再来一局'
		restartElement.addEventListener('click', showConfigContainer)
		choicesElement.appendChild(restartElement)

		addElement(choicesElement)
	} else {
		// Render current round
		const round = game.round
		addTextElement(round.name, 'title')
		addTextElement(`牌山余&nbsp;${round.pile.length}&nbsp;张`)
		let players = []
		const lastPlaying = (playing.lastIndexOf(true) + playerCount) % playerCount
		for (let i = 1; i <= playerCount; ++i)
			players.push((lastPlaying + i) % playerCount)

		for (const playerId of players) {
			const player = round.players[playerId]
			const hu = player.hu
			const tenpai = player.tenpai
			const tenpaiHint = player.tenpaiHint
			addTextElement()
			addTextElement(PLAYER_NAMES[playerId] + '（得分：' + game.points[playerId] + '）' + (hu ? `<span class="green">${stringifyHu(hu)}</span>` : (tenpai ? `<span class="lime">${stringifyTenpai(tenpai)}</span>` : (tenpaiHint ? `<span class="lime">听牌</span>` : ''))) + (round.players[playerId].dealIn ? `<span class="red">${round.players[playerId].dealIn.map(stringifyDealIn).join('')}</span>` : ''), playing[playerId] ? 'bold' : '')

			const ended = round.ended
			const play = playing[playerId]
			const addChoices = !ended && play && round.phase !== PHASE_DISCARD && !player.choice
			const addDiscard = !ended && play && round.phase === PHASE_DISCARD && round.toPlay === playerId
			const discardLast = round.phase === PHASE_MELD && round.toPlay === playerId
			const choices = addChoices ? player.choices : []
			const choosing = addChoices ? (choice => setChoice(round, playerId, choice)) : undefined
			const discarding = addDiscard ? (tile => setChoice(round, playerId, [CHOICE_DISCARD, tile])) : undefined
			const ending = ended && playerId === lastPlaying ? (() => advanceGameRound(game)) : undefined
			addPlayerElement(player, play, choices, choosing, discarding, discardLast, ended, ending)
		}
	}
}